<template>
  <div class="vue-formula-editor">
    <el-row :gutter="8">
      <el-col :span="6">
        <div class="vfe-title">字段列表</div>
        <el-tree :data="fieldList" :props="fieldTreeProps">
          <template #default="{ node, data }">
            <div
              class="custom-tree-node"
              @mouseenter="showFieldButton(node)"
              @mouseleave="hideFieldButton(node)"
            >
              <span>{{ node.label }}</span>
              <span v-if="hoverNode === node" class="tree-node-actions">
                <el-button size="mini" @click="onFieldNameSelect(data)">名称</el-button>
                <el-button size="mini" @click="onFieldValueSelect(data)">值</el-button>
              </span>
            </div>
          </template>
        </el-tree>
      </el-col>
      <el-col :span="18">
        <codemirror class="vfe-codemirror" @ready="onCmReady" v-model="code" :options="options" />
      </el-col>
    </el-row>
    <el-row :gutter="8">
      <el-col :span="6">
        <div class="vfe-title">函数/变量类型</div>
        <div
          :class="{vfeFormulaType: true,vfeFormulaTypeActive: currentFormulaType && currentFormulaType.code ===  formulaType.code}"
          v-for="formulaType in formulaTypeList" @click="onFormulaTypeClick(formulaType)"
          style="height: 24px;">
          {{ formulaType.name }}
        </div>
      </el-col>
      <el-col :span="6">
        <div class="vfe-title">函数/变量</div>
        <div :class="{vfeFormula: true, vfeFormulaActive: currentFormula && currentFormula.name ===  formula.name}"
             v-for="formula in formulaList" @click="onFormulaItemClick(formula)">
          <div class="vfe-formula-name">{{ formula.name }}</div>
          <div class="vfe-formula-desc">{{ formula.desc }}</div>
        </div>
      </el-col>
      <el-col :span="12">
        <div class="vfe-title">手册</div>
        <div class="vfe-help">
          <el-button type="primary" plain @click="onFormulaClick(currentFormula)" size="mini">插入函数</el-button>
          <div class="vfe-help-block">
            <p class="vfe-help-title">{{ currentFormula.name }}：</p>
            <p class="vfe-help-desc">{{ currentFormula.desc }}</p>
          </div>
          <div class="vfe-help-block">
            <p class="vfe-help-title">语法：</p>
            <p class="vfe-help-desc">{{ currentFormula.grammar }}</p>
          </div>
          <div class="vfe-help-block">
            <p class="vfe-help-title">示例：</p>
            <p class="vfe-help-desc">{{ currentFormula.example }}</p>
          </div>
          <div class="vfe-help-block" v-for="formulaParam in currentFormula.params">
            <p class="vfe-help-title">{{ formulaParam.name }}：</p>
            <p class="vfe-help-desc">
              <span class="vfe-required" v-if="formulaParam.required">必需</span>
              <span class="vfe-not-required" v-else>可选</span>
              {{ formulaParam.desc }}</p>
          </div>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
  // 组件样式
  import 'codemirror/lib/codemirror.css'
  // 主题
  import 'codemirror/theme/idea.css'
  import 'codemirror/theme/ayu-mirage.css'
  import 'codemirror/theme/monokai.css'
  // 语言模式
  import 'codemirror/mode/javascript/javascript.js'
  import 'codemirror/addon/hint/show-hint.css'
  import 'codemirror/addon/hint/show-hint.js'
  import { codemirror } from 'vue-codemirror'
  import FormulaEditorCore from './core/index'

  export default {
    name: 'vue-formula',
    components: {
      codemirror,
    },
    props: {
      fieldList: {
        type: Array,
        default: () => [],
      },
      formulaTypeList: {
        type: Array,
        default: () => [],
      },
      formulaConf: {
        type: Object,
        default: () => ({}),
      },
    },
    data() {
      return {
        editorCore: null,
        code: '',
        formulaList: [],
        currentFormulaType: null,
        currentFormula: {
          'name': '',
          'desc': '',
          'grammar': '',
          'example': '',
          'params': [],
        },
        fieldTreeProps: {
          children: 'children',
          label: 'fieldName',
        },
        hoverNode: null,
        validInfo: '',
        options: {
          mode: 'javascript',
          autofocus: true,
          autoCloseBrackets: true,
          line: true,
          gutters: true,
          height: 200,
          theme: 'idea', // 主题
          tabSize: 4, // 制表符的宽度
          readOnly: false, // 只读
          smartIndent: true, // 上下文缩进
          lineNumbers: true, // 是否显示行号
          lineWrapping: false, // 自动换行
          styleActiveLine: true, // 高亮选中行
          showCursorWhenSelecting: true, // 当选择处于活动状态时是否应绘制游标
        },
      }
    },
    methods: {
      showFieldButton(node){
        this.hoverNode = node
      },
      hideFieldButton(node){
        this.hoverNode = null
      },
      onFormulaTypeClick(formulaType) {
        this.currentFormulaType = formulaType
        this.formulaList = formulaType.formulaList
        // 设置默认第一个函数激活
        this.currentFormula = formulaType.formulaList[0]
      },
      onFormulaItemClick(formula) {
        this.currentFormula = formula
      },
      reset() {
        this.currentFormula = null
        this.editorCore.reset()
      },
      getData() {
        return this.editorCore.getData()
      },
      // codemirror 初始化时执行
      onCmReady(codemirror) {
        this.editorCore = new FormulaEditorCore(
          codemirror,
          '',
          this.formulaTypeList,
        )
        // 注册 'change', 'inputRead', 'beforeChange' 等事件
        this.editorCore.registerListen()

        this.editorCore.renderData(this.formulaConf)
      },
      /**
       * 点击插入函数按钮时，将函数名称插入到当前光标所在的位置
       * @param formula
       */
      onFormulaClick(formula) {
        this.currentFormula = formula
        this.editorCore.insertText(`${formula.name}()`, 'formula')
      },
      /**
       * 点击插入字段按钮
       * @param field
       */
      onFieldSelect(field) {
        this.editorCore.insertText(
          {
            ...field
          },
          'field',
        )
      },
      onFieldNameSelect(field) {
        this.editorCore.insertText(
          {
            ...field,
            "markType": 'fieldName'
          },
          'field',
        )
      },
      onFieldValueSelect(field) {
        this.editorCore.insertText(
          {
            ...field,
            "markType": 'fieldValue'
          },
          'field',
        )
      }
    },
  }
</script>
<style lang="less" scoped>
  .vue-formula-editor {
    .vfeFormulaType {
      font-size: 14px;
      height: 35px;
      padding: 4px 8px;
      color: #333333;

      &:hover {
        color: #007aff;
        background-color: #eaf2fd;
        cursor: pointer;
      }
    }

    .vfeFormulaTypeActive {
      color: #007aff;
    }

    .vfeFormula {
      height: 35px;
      padding: 4px 8px;
      color: #333333;

      &:hover {
        color: #007aff;
        background-color: #eaf2fd;
        cursor: pointer;
      }

      .vfe-formula-name {
        font-size: 14px;
      }

      .vfe-formula-desc {
        font-size: 12px;
        color: #999999;
        white-space: nowrap; /* 强制文本不换行 */
        overflow: hidden; /* 隐藏超出容器的内容 */
        text-overflow: ellipsis; /* 显示省略号 */
        width: 100%; /* 或指定固定宽度 */
      }
    }

    .vfeFormulaActive {
      color: #007aff;
    }

    .vfe-help {
      .vfe-help-block {
        margin-top: 0px;
      }

      .vfe-help-title {
        font-size: 14px;
        color: #999999;
      }

      .vfe-help-desc {
        font-size: 12px;
        color: #333333;
      }

      .vfe-required {
        background-color: #007aff20;
        color: #007aff;
        display: inline-block;
        width: 40px;
        padding: 0 4px;
        text-align: center;
      }

      .vfe-not-required {
        background-color: #d7d9dc;
        color: white;
        display: inline-block;
        width: 40px;
        padding: 0 4px;
        text-align: center;
      }
    }
  }


</style>

<style lang="less">
  /** 不能是局部样式，否则不生效 */
  .cm-field-name {
    color: #007aff !important;
    border-radius: 2px;
    display: inline-block;
    font-size: 14px;
    margin: 0 2px;
    padding: 3px 5px;
  }

  .cm-field-value {
    background: #007aff20;
    color: #007aff !important;
    border-radius: 2px;
    display: inline-block;
    font-size: 14px;
    margin: 0 2px;
    padding: 3px 5px;
  }


  .CodeMirror-hints {
    z-index: 30000 !important;
    background-color: #f0f0f0;
    color: #333;
    width: 130px;
    font-size: 14px;
    border: 1px solid #ccc;
    padding: 10px;
    border-radius: 4px;
    max-height: 200px;
    overflow-y: auto;
  }

  .vfe-title {
    font-weight: bold;

    &::before {
      content: ""; /* 伪元素必须设置 content 属性 */
      position: absolute; /* 绝对定位 */
      left: -8px; /* 定位到 div 的最左侧 */
      width: 3px; /* 竖线宽度 */
      height: 20px; /* 竖线高度 */
      background-color: #007aff; /* 竖线颜色 */
    }
  }
</style>